package br.com.pedrosilva.fv.gui;

import java.awt.Image;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.filechooser.FileSystemView;

import br.com.pedrosilva.fv.util.Util;

/**
 * Janela principal da aplicação.
 * @author Pedro C. Silva - 94665516553
 *
 */
public class MainWindow extends javax.swing.JFrame {

	private static final long serialVersionUID = -7875491069968862357L;
	private static final String NEWLINE = System.getProperty("line.separator");
	private static final String FILENAME_REGEXP = "^(([a-zA-Z]:\\\\)*|/{1})[\\w-./\\\\]*";
	private static final int ACTION_OPEN = 0;
	private static final int ACTION_SAVE = 1;
	private int files = 0;
	

	/** Creates new form MainWindow */
    public MainWindow() {
    	initFileChooser();
        initComponents();
        setIconImages(getImages());
    }
    
	/**
	 * Inicializa o componente JFileChooser.
	 */
	private void initFileChooser() {
		openFileChooser = new JFileChooser();
		openFileChooser.setFileSystemView(FileSystemView.getFileSystemView());
		openFileChooser.setAcceptAllFileFilterUsed(false);
		openFileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Todos os arquivos (*.*)", "*"));
		openFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		openFileChooser.setDialogTitle("Selecione VOB para verificação...");

		saveFileChooser = new JFileChooser();
		saveFileChooser.setFileSystemView(FileSystemView.getFileSystemView());
		saveFileChooser.setAcceptAllFileFilterUsed(false);
		saveFileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Arquivos Texto (*.txt)", "txt"));
		saveFileChooser.setCurrentDirectory(new File(Util.getDesktopFolder()));
		saveFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		saveFileChooser.setDialogTitle("Salvar...");
		
	}

	/**
	 * Retorna uma pasta selecionada para verificação.
	 * 
	 * @return Pasta selecionada.
	 */
	private File getSelectedFile(int action) {
		int result;
		if(action == ACTION_OPEN){
			result = openFileChooser.showOpenDialog(this);
		}			
		else{
			saveFileChooser.setSelectedFile(new File(getFileName()));
			result = saveFileChooser.showSaveDialog(this);			
		}			
		if (result != JFileChooser.CANCEL_OPTION)
			return (action == ACTION_OPEN) ? openFileChooser.getSelectedFile() : saveFileChooser.getSelectedFile();
		else
			return null;
	}

	/***
	 * Retorna o nome do arquivo de relatório da verificação.
	 * @return Nome do arquivo.
	 */
	private String getFileName(){
		StringBuilder builder = new StringBuilder();
		builder.append("RELATORIO-");
		builder.append(Util.getFileName(pathTxt.getText()));
		builder.append("-");
		builder.append(Util.getDate(Util.DATE_FORMAT));
		builder.append(".txt");
		return builder.toString();
	}
	
	/**
	 * Inicia a verificação de arquivos e pastas.
	 */
	private void doVerification(){
		Thread runner = new Thread(){
			public void run(){
				File file = getSelectedFile(ACTION_OPEN);
				if(file != null) {
					filesTxt.setText("");
					pathTxt.setText(file.getAbsolutePath());
					progressBar.setIndeterminate(true);
					try {
						verify(file);
					} catch (Exception e) {
						e.printStackTrace();
					}
					statusLabel.setText("Concluído!");
					progressBar.setIndeterminate(false);
				}
			}			
		};
		runner.start();
	}
	
	/**
	 * Efetua a verificação de arquivos e pastas.
	 * @param rootDir
	 * @throws IOException
	 */
	private void verify(File rootDir) throws IOException {
		if (rootDir.exists()) {
			File[] items = rootDir.listFiles();
			for(int i = items.length - 1; i >= 0; i--){
				if(items[i].isDirectory())
					verify(items[i]);				
				else {
					statusLabel.setText(Util.trimToSize(items[i].getParent(), statusLabel.getWidth() / 6)); 
					if(!items[i].getAbsolutePath().matches(FILENAME_REGEXP)){
						filesTxt.append(items[i].getAbsolutePath() + NEWLINE);
						files++;
					}						
				}				
			}
		}
	}

	/**
	 * Salva as informações levantadas em um arquivo texto.
	 */
	private void save() {
		if (!filesTxt.getText().trim().equals("")) {
			Thread runner = new Thread() {
				public void run() {
					try {
						File file = getSelectedFile(ACTION_SAVE);
						if (file != null) {
							progressBar.setIndeterminate(true);
							FileWriter fw = new FileWriter(file);
							BufferedWriter bfw = new BufferedWriter(fw);
							bfw.write("ARQUIVOS E DIRETÓRIOS COM NOMENCLATURA IRREGULAR");
							bfw.newLine();
							bfw.write("------------------------------------------------");
							bfw.newLine();
							bfw.write(filesTxt.getText());
							bfw.newLine();
							bfw.write("Total: " + files);
							bfw.newLine();
							bfw.close();
							fw.close();
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
					finally{
						progressBar.setIndeterminate(false);	
					}
				}
			};
			runner.start();
		}
	}
	
	/**
	 * Cria os ícones da janela principal da aplicação.
	 * 
	 * @return Lista de Imagens.
	 */
	private List<Image> getImages() {
		List<Image> images = new ArrayList<Image>();
		images.add(new javax.swing.ImageIcon(getClass().getResource("/resources/icons/fileview-detailed16.png")).getImage());
		images.add(new javax.swing.ImageIcon(getClass().getResource("/resources/icons/fileview-detailed22.png")).getImage());
		images.add(new javax.swing.ImageIcon(getClass().getResource("/resources/icons/fileview-detailed32.png")).getImage());
		images.add(new javax.swing.ImageIcon(getClass().getResource("/resources/icons/fileview-detailed48.png")).getImage());
		return images;
	}

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        progressBar = new javax.swing.JProgressBar();
        saveBtn = new javax.swing.JButton();
        scroll = new javax.swing.JScrollPane();
        filesTxt = new javax.swing.JTextArea();
        statusLabel = new javax.swing.JLabel();
        topPanel = new javax.swing.JPanel();
        folderBtn = new javax.swing.JButton();
        pathTxt = new javax.swing.JTextField();

        FormListener formListener = new FormListener();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("File Verifier");

        saveBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/icons/save.gif"))); // NOI18N
        saveBtn.setToolTipText("Salvar");
        saveBtn.addActionListener(formListener);

        scroll.setBorder(javax.swing.BorderFactory.createTitledBorder("Resultado: "));

        filesTxt.setColumns(20);
        filesTxt.setRows(5);
        scroll.setViewportView(filesTxt);

        topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Selecione um Diretório: "));

        folderBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/icons/folder.gif"))); // NOI18N
        folderBtn.setToolTipText("Selecione uma pasta");
        folderBtn.addActionListener(formListener);

        pathTxt.setEditable(false);

        org.jdesktop.layout.GroupLayout topPanelLayout = new org.jdesktop.layout.GroupLayout(topPanel);
        topPanel.setLayout(topPanelLayout);
        topPanelLayout.setHorizontalGroup(
            topPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, topPanelLayout.createSequentialGroup()
                .add(pathTxt, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 621, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(folderBtn))
        );
        topPanelLayout.setVerticalGroup(
            topPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(topPanelLayout.createSequentialGroup()
                .add(topPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(folderBtn)
                    .add(pathTxt, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 25, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(topPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(layout.createSequentialGroup()
                .add(6, 6, 6)
                .add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 102, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(statusLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 517, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(saveBtn)
                .addContainerGap())
            .add(scroll, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(topPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(scroll, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 257, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.CENTER)
                    .add(progressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(statusLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 25, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(saveBtn))
                .add(6, 6, 6))
        );

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-700)/2, (screenSize.height-400)/2, 700, 400);
    }

    // Code for dispatching events from components to event handlers.

    private class FormListener implements java.awt.event.ActionListener {
        FormListener() {}
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            if (evt.getSource() == saveBtn) {
                MainWindow.this.saveBtnActionPerformed(evt);
            }
            else if (evt.getSource() == folderBtn) {
                MainWindow.this.folderBtnActionPerformed(evt);
            }
        }
    }// </editor-fold>//GEN-END:initComponents

    private void folderBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_folderBtnActionPerformed
    	doVerification();
    }//GEN-LAST:event_folderBtnActionPerformed

    private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveBtnActionPerformed
        save();
    }//GEN-LAST:event_saveBtnActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextArea filesTxt;
    private javax.swing.JButton folderBtn;
    private javax.swing.JTextField pathTxt;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JButton saveBtn;
    private javax.swing.JScrollPane scroll;
    private javax.swing.JLabel statusLabel;
    private javax.swing.JPanel topPanel;
    // End of variables declaration//GEN-END:variables
    private JFileChooser openFileChooser;
    private JFileChooser saveFileChooser;

}
